home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / ptv1n2.arc / DRAW.C < prev    next >
C/C++ Source or Header  |  1990-06-14  |  10KB  |  236 lines

  1. /* draw.c -- Interactive drawing utilities used by the simple
  2.  * paint program paint.c
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <graphics.h>
  7. #include <alloc.h>
  8. #include <stdlib.h>
  9. #include <time.h>
  10. #include "mouse.h"           /* Function prototypes for mouse */
  11. #include "draw.h"            /* Function prototypes for draw.c */
  12.  
  13. /*   The fill parameters, drawing colors, and so forth are all kept as global
  14.  *   variables. From time to time the current drawing, fill, and line
  15.  *   styles may be changed, so before calling any drawing function make sure
  16.  *   the various drawing parameters are reset to these global values.
  17.  */
  18. int globalfillstyle;  /* The fill style that should be used */
  19. int globalfillcolor;  /* Holds the fill color that should be used */
  20. int globaldrawcolor;  /* Holds the drawing color to use */
  21. int globallinestyle;  /* Holds the line style that should be used */
  22. int wl, wt, wr, wb;   /* Window bounds where drawing is to be done */
  23.  
  24. /*  This routine emulates a pencil. While the left mouse button is pressed
  25.  *  it will draw a trail of connected lines. When the mouse button is
  26.  *  released, no drawing occurs. To avoid unneccassary drawing, lines are
  27.  *  only drawn when the mouse's position changes.
  28.  */
  29. void pencil(void)
  30. {
  31.     int x, y, oldx, oldy;
  32.  
  33.     setviewport(wl,wt,wr,wb,1);        /* Draw in this viewport location */
  34.     setcolor(globaldrawcolor);         /* Use the global drawing color */
  35.     while (1) {
  36.     while (!buttonstatus(PRESSED,LEFT_BUTTON)) ; /* Wait until button is */
  37.         getmousecoords(&x,&y);              /* pressed, Get coordinates. */
  38.     if (x < wl || x > wr || y < wt || y > wb) {   /* If mouse location outside */
  39.             setviewport(0,0,getmaxx(),getmaxy(),1);        /* of window */
  40.             return;                  /* restore viewport to full screen */
  41.         }                            /* and exit pencil routine */
  42.         oldx = x;  oldy = y;
  43.         moveto(x-wl,y-wt);           /* Set current position to */
  44.                                      /* where drawing begins */
  45.                                      /* As long as the mouse button is */
  46.     mousestatus(HIDE_MOUSE);          /* Erase the screen where the mouse */
  47.     mousestatus(SHOW_MOUSE);
  48.     while (!buttonstatus(RELEASED,LEFT_BUTTON)) {  /* pressed, get its */
  49.             getmousecoords(&x,&y);            /* location. If location has */
  50.             if (x != oldx || y != oldy) {     /* has changed, draw a line */
  51.         mousestatus(HIDE_MOUSE);      /* to it. Make sure to */
  52.                 lineto(x-wl,y-wt);            /* adjust mouse location */
  53.         mousestatus(SHOW_MOUSE);      /* to current viewport. */
  54.                 oldx = x;  oldy = y;          /* Save mouse location */
  55.             }
  56.         }
  57.     }
  58. }
  59.  
  60. /*  This routine resets a small block of the screen to the background
  61.  *  color. The erasing is done by drawing a filled bar at the current
  62.  *  mouse location as long as the left mouse button is pressed.
  63.  */
  64. void erase(void)
  65. {
  66.     int x, y, oldx, oldy;
  67.  
  68.     setviewport(wl,wt,wr,wb,1);      /* Set the viewport to the drawing */
  69.     setcolor(getbkcolor());          /* window. Use the background color */
  70.     setfillstyle(SOLID_FILL,getbkcolor());      /* to erase the screen. */
  71.     while (1) {
  72.     while (!buttonstatus(PRESSED,LEFT_BUTTON));/* Wait for button press */
  73.         getmousecoords(&x,&y);                  /* Get mouse location */
  74.     if (x < wl || x > wr || y < wt || y > wb) {       /* If mouse outside of */
  75.             setviewport(0,0,getmaxx(),getmaxy(),1);      /* window, then*/
  76.             return;                      /* restore viewport and return. */
  77.         }
  78.         oldx = x;  oldy = y;
  79.     mousestatus(HIDE_MOUSE);          /* Erase the screen where the mouse */
  80.         bar(x-wl,y-wt,x-wl+ERASERSIZE,y-wt+ERASERSIZE);  /* is located */
  81.     mousestatus(SHOW_MOUSE);
  82.     while (!buttonstatus(RELEASED,LEFT_BUTTON)) { /* Continue to erase */
  83.             getmousecoords(&x,&y);                /* the screen as long */
  84.             if (x != oldx || y != oldy) {         /* as the mouse is at */
  85.         mousestatus(HIDE_MOUSE);                      /* a new location and */
  86.                 bar(x-wl,y-wt,x-wl+ERASERSIZE,y-wt+ERASERSIZE);
  87.         mousestatus(SHOW_MOUSE);          /* the left button is */
  88.                 oldx = x;   oldy = y;             /* pressed */
  89.             }
  90.         }
  91.     }
  92. }
  93.  
  94. /*  The spraycan routine randomly paints pixels in a square region
  95.  *  whenever the left mouse button is pressed.
  96.  */
  97. void spraycan(void)
  98. {
  99.     int i, x, y;
  100.  
  101.     randomize();                        /* Begin random function used to */
  102.                                         /* decide where to paint pixels */
  103.     setviewport(wl,wt,wr,wb,1);         /* Set window to drawing window */
  104.     while (1) {                                   /* Wait until the left */
  105.     while (!buttonstatus(PRESSED,LEFT_BUTTON)); /* button is pressed */
  106.         getmousecoords(&x,&y);                    /* If mouse is outside */
  107.     if (x < wl || x > wr || y < wt || y > wb) {         /* of draw window then */
  108.             setviewport(0,0,getmaxx(),getmaxy(),1);    /* restore window */
  109.             return;                               /* to full screen and */
  110.         }                                         /* quit routine */
  111.     while (!buttonstatus(RELEASED,LEFT_BUTTON)) {/* Continue spraying */
  112.             getmousecoords(&x, &y);                /* while the button is */
  113.         mousestatus(HIDE_MOUSE);                           /* pressed */
  114.             for (i=0; i<8; i++)
  115.                 putpixel(x-random(SPRAYSIZE)+5-wl,
  116.                     y-random(SPRAYSIZE)+5-wt, globaldrawcolor);
  117.             for (i=0; i<8; i++)
  118.                 putpixel(x-random(SPRAYSIZE-2)+3-wl,
  119.                     y-random(SPRAYSIZE-2)+3-wt, globaldrawcolor);
  120.         mousestatus(SHOW_MOUSE);
  121.         }
  122.     }
  123. }
  124.  
  125. /*  Draw a line while line left mouse button is pressed. Use
  126.  *  XOR_PUT to provide rubber-banding line feature. Once a line
  127.  *  is to be fixed it is redrawn with COPY_PUT so that the color
  128.  *  for the line will be drawn correctly, since XOR_PUT won't always
  129.  *  yield the correct colors.
  130.  */
  131. void drawlines(void)
  132. {
  133.     int x1, y1, x2, y2, oldx2, oldy2;
  134.  
  135.     setviewport(wl,wt,wr,wb,1);                  /* Use the drawing window */
  136.     setlinestyle(globallinestyle,0,NORM_WIDTH);  /* and the global */
  137.     setcolor(globaldrawcolor);                   /* settings */
  138.     while (1) {
  139.     while (!buttonstatus(PRESSED,LEFT_BUTTON)) ;
  140.         getmousecoords(&x1,&y1);
  141.     if (x1 < wl || x1 > wr || y1 < wt || y1 > wb) {
  142.             setviewport(0,0,getmaxx(),getmaxy(),1);
  143.             setwritemode(COPY_PUT);
  144.             return;
  145.         }
  146.         setwritemode(XOR_PUT);         /* Use XOR_PUT to rubber-band lines */
  147.         moveto(x1-wl,y1-wt);
  148.         oldx2 = x1;   oldy2 = y1;
  149.     while (!buttonstatus(RELEASED,LEFT_BUTTON)) {
  150.             getmousecoords(&x2,&y2);
  151.             if (x2 != oldx2 || y2 != oldy2) {
  152.         mousestatus(HIDE_MOUSE);
  153.                 line(x1-wl,y1-wt,oldx2-wl,oldy2-wt);
  154.                 line(x1-wl,y1-wt,x2-wl,y2-wt);
  155.         mousestatus(SHOW_MOUSE);
  156.                 oldx2 = x2;  oldy2 = y2;
  157.             }
  158.         }
  159.         setwritemode(COPY_PUT);           /* Redraw line when set */
  160.     mousestatus(HIDE_MOUSE);                      /* so color will be */
  161.         line(x1-wl,y1-wt,x2-wl,y2-wt);    /* correct */
  162.     mousestatus(SHOW_MOUSE);
  163.     }
  164. }
  165.  
  166. /*  Interactively draw a circle */
  167. void drawcircle(void)
  168. {
  169.   int cleft, ctop, cright, cbottom, absradius;
  170.   unsigned char far *covered1, *covered2;
  171.   int centerx, centery, oldleft, oldtop;
  172.   int halfx, newx, newy, oldx;
  173.  
  174.   halfx = (wr + wl) / 2;
  175.   covered1 = malloc(imagesize(wl, wt, halfx, wb));
  176.   covered2 = malloc(imagesize(halfx+1, wt, wr, wb));
  177.   if (covered1 == NULL || covered2 == NULL) {
  178.     mallocerror();
  179.   }
  180.   setcolor(globaldrawcolor);
  181.   setviewport(wl, wt, wr, wb, 1);
  182.   while (1) {
  183.     while (!buttonstatus(PRESSED,LEFT_BUTTON)) ;
  184.     getmousecoords(¢erx, ¢ery);
  185.     if (centerx < wl || centerx > wr || centery < wt || centery > wb) {
  186.       setviewport(0, 0, getmaxx(), getmaxy(),1);
  187.       free(covered2);
  188.       free(covered1);
  189.       return;
  190.     }
  191.     oldleft = centerx;  oldtop = centery;   oldx = centerx;
  192.     mousestatus(HIDE_MOUSE);
  193.     getimage(oldleft-wl, oldtop-wt, oldleft-wl, oldtop-wt, covered1);
  194.     getimage(oldleft+1-wl, oldtop-wt, oldleft+1-wl, oldtop-wt, covered2);
  195.     mousestatus(SHOW_MOUSE);
  196.     while (!buttonstatus(RELEASED,LEFT_BUTTON)) {
  197.       getmousecoords(&newx, &newy);
  198.       absradius = abs(centerx - newx);
  199.  
  200.       /* Clip the region that must be saved below the circle
  201.        * to the boundaries of the drawing window
  202.        */
  203.       if (centerx-absradius < wl) cleft = wl;
  204.         else cleft = centerx - absradius;
  205.       if (centerx+absradius > wr) cright = wr;
  206.         else cright = centerx + absradius;
  207.       if (centery-absradius < wt) ctop = wt;
  208.         else ctop = centery - absradius;
  209.       if (centery+absradius > wb) cbottom = wb;
  210.         else cbottom = centery + absradius;
  211.  
  212.       /* If the size of the circle has changed, redraw it */
  213.       if (newx != oldx) {
  214.     mousestatus(HIDE_MOUSE);
  215.     putimage(oldleft-wl, oldtop-wt, covered1, COPY_PUT);
  216.     putimage(centerx+1-wl, oldtop-wt, covered2, COPY_PUT);
  217.     getimage(cleft-wl, ctop-wt, centerx-wl, cbottom-wt, covered1);
  218.     getimage(centerx+1-wl, ctop-wt, cright-wl, cbottom-wt, covered2);
  219.     if (absradius != 0)
  220.       circle(centerx-wl, centery-wt, absradius);
  221.     mousestatus(SHOW_MOUSE);
  222.     oldleft = cleft;   oldtop = ctop;   oldx = newx;
  223.       }
  224.     }
  225.   }
  226. }
  227.  
  228. /* This function is called if a malloc() fails. Place your
  229.  * own error handler here.
  230.  */
  231. void mallocerror(void)
  232. {
  233.   closegraph();
  234.   printf("Not enough memory");
  235.   exit(1);
  236. }